#ifndef __WIZ_UTILS_FINITE_AUTOMATON_TEMPLATE_HPP__SHANHAOBO_19800429__
#define __WIZ_UTILS_FINITE_AUTOMATON_TEMPLATE_HPP__SHANHAOBO_19800429__

#include "../Base/WizBase.hpp"

namespace Wiz
{
    namespace NFA
    {
        namespace Node
        {
            template<class LikT>
            class Type
            {
                typedef Type									tThis;
                typedef ::Wiz::Set::Type<tThis*>				thisTypeSet;
                typedef ::Wiz::Map::Type<LikT, thisTypeSet>		TransTable;
            public:
                Type()
                {
                }
            public:
                ::Wiz::Void::Type GoTo(LikT Lik, tThis* NodePtr)
                {
					WIZ_ASSERT(::Wiz::IsValidPtr(NodePtr));
                    TransTable::tIterator Itr = m_TransTable.Find(Lik);
                    if (Itr == m_TransTable.End())
                    {
                        Itr = m_TransTable.Insert(Lik, thisTypeSet());
                    }

                    if (Itr != m_TransTable.End())
                    {
                        Itr.GetValue().Insert(Lik, NodePtr);
                    }
                }
                ::Wiz::Bool::Type GetNodeSet(LikT Lik, thisTypeSet& STS)
                {
                    TransTable::tIterator Itr = m_TransTable.Find(Lik);
                    if (Itr == m_TransTable.End())
                    {
                        return ::Wiz::Bool::False;
                    }
                    STS = Itr.GetValue();
                    return ::Wiz::Bool::True;
                }
            protected:
                TransTable                          m_TransTable;
            };
        } /// end of namespace Node

        template<class ParamT> class Type;
    } /// end of namespace NFA

    namespace DFA
    {
        namespace Node
        {
            template<class LikT>
            class Type
            {
                typedef Type								tThis;
                typedef ::Wiz::Map::Type<LikT, tThis*>	TransTable;
            public:
                Type()
                {
                }
            public:
                ::Wiz::Void::Type GoTo(LikT Lik, tThis* NodePtr)
                {
                    m_TransTable.Insert(Lik, NodePtr);
                }
                tThis* GetNode(LikT Lik)
                {
                    TransTable::tIterator Itr = m_TransTable.Find(Lik);
                    if (Itr == m_TransTable.End())
                    {
                        return WIZ_NULLPTR;
                    }
                    return Itr.GetValue();
                }
            protected:
                TransTable                          m_TransTable;
            };
        } /// end of namespace Node

        template<class ParamT> class Type;
    } /// end of namespace DFA
} /// end of namespace Wiz

#endif /*__WIZ_UTILS_FINITE_AUTOMATON_TEMPLATE_HPP__SHANHAOBO_19800429__*/

#if defined(WIZ_FA_PARAM_COUNT) && (WIZ_FA_PARAM_COUNT >= 0) && (WIZ_FA_PARAM_COUNT < 255)

namespace Wiz
{
    namespace NFA
    {
        template<class LikT WIZ_COMMA_IF(WIZ_FA_PARAM_COUNT) WIZ_ENUM_PARAM_X(WIZ_FA_PARAM_COUNT, class T)>
        class Type<LikT(WIZ_ENUM_PARAM_X(WIZ_FA_PARAM_COUNT, T))>
        {
            typedef ::Wiz::NFA::Node::Type<LikT>    tNode;
        public:
            Type(){}
            virtual ~Type(){}
        public:
            ::Wiz::Bool::Type Insert(tNode* NPtr)
            {
                return m_Set.Insert(NPtr);
            }
			tNode* Create()
			{
				tNode* nodePtr = new tNode();
				if (::Wiz::NotValidPtr(nodePtr))
				{
					return WIZ_NULLPTR;
				}
				if (m_Set.Insert(nodePtr))
				{
					return nodePtr;
				}
				::Wiz::SafeDelete(nodePtr);
				return WIZ_NULLPTR;
			}
        protected:
            typedef ::Wiz::Set::Type<tNode*> tNodeSet;
            tNodeSet	    m_Set;
            tNode*			m_Begin;
            tNode*			m_End;
        };
    } /// end of namespace NFA

    namespace DFA
    {
        template<class LikT WIZ_COMMA_IF(WIZ_FA_PARAM_COUNT) WIZ_ENUM_PARAM_X(WIZ_FA_PARAM_COUNT, class T)>
        class Type<LikT(WIZ_ENUM_PARAM_X(WIZ_FA_PARAM_COUNT, T))>
        {
            typedef ::Wiz::DFA::Node::Type<LikT>    tNode;
        public:
            Type()
            {}
            virtual ~Type()
            {}
        public:
            ::Wiz::Bool::Type Insert(tNode* nodePtr)
            {
                return m_Set.Insert(nodePtr);
			}
			tNode* Create()
			{
				tNode* nodePtr = new tNode();
				if (::Wiz::NotValidPtr(nodePtr))
				{
					return WIZ_NULLPTR;
				}
				if (m_Set.Insert(nodePtr))
				{
					return nodePtr;
				}
				::Wiz::SafeDelete(nodePtr);
				return WIZ_NULLPTR;
			}
        protected:
            typedef ::Wiz::Set::Type<tNode*> tNodeSet;
            tNodeSet			m_Set;
            tNode*			    m_Begin;
            tNode*			    m_End;
        };
    } /// end of namespace DFA
} /// end of namespace Wiz

#endif /*defined(WIZ_FA_PARAM_COUNT) && (WIZ_FA_PARAM_COUNT >= 0) && (WIZ_FA_PARAM_COUNT < 255)*/
